home *** CD-ROM | disk | FTP | other *** search
- {
- Resizer.Pas
- ***********
-
- TTabbedNotebook functionality added by:
-
- Jeff Kinzer
- 102413,2557
- }
-
- {*
- * NO THIS IS NOT PERFECT. IF YOU DON'T LIKE IT, DON'T USE IT!
- *
- * This is a simple VC that resizes all the controls on a form.
- *
- * All you have to do is place the RESIZER component on your form,
- * set the 'OnSized' event for the form to a function and then call
- * 'ReSize(Sender)' from within that function.
- *
- * It is a GOOD IDEA in your 'OnSized' event for the form to watch
- * for resizing that is too small. If you resize the form too small
- * you can cause this Resizer to crash your program. All you have to
- * do is check the bounds of the form being resized, if they are less
- * than a certain amount, set the bounds to the certain amount.
- *
- * See the example program for help or you can mail me:
- * mental@murdrum.nmsu.edu
- *
- * Obvious extensions are adding support to any container controls I
- * may have missed. You can tell if something is a container control
- * by placing another control on it and then try to move the control
- * outside of it. If you cannot move the inner control outside, it
- * IS a container control.
- * I have NOT figured out how controls are stored on a TTabbedNotebook,
- * (but honently I have not looked very hard, yet) so while the
- * TTabbedNotebook will resize itself, the obejcts on the pages will
- * not size themselvess.
- *}
-
- unit Resizer;
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, ExtCtrls, StdCtrls, TabNotBk;
-
- type
- pControlInfo = ^tControlInfo;
- tControlInfo = record
- { This record holds information about a component on the form}
- { or about a component inside a container object}
- Obj:TControl;
- ClassName:String;
- lRatio,tRatio,wRatio,hRatio:Real;
- Contains:pControlInfo;
- Next:pControlInfo;
- End;
- TResizer = class(TComponent)
- private
- { These variables and functions should not be needed by the user, }
- { only by the RESIZER component.}
- ResizerInitialized:Boolean;
- Function GetClientControlCount(Sender:TObject):LongInt;
- procedure GetNewWidthHeight(Sender:TObject;Var NewW,NewH:LongInt);
- Procedure PerformResize(CurCont:pControlInfo;CWidth,CHeight:LongInt);
- Function GetClientControlObject(Sender:TObject;Index:LongInt):TControl;
- Function Initialize(Sender:TObject;CWidth,CHeight:LongInt):pControlInfo;
- Procedure DeleteControlList(CurCont:pControlInfo);
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- { These are useful to the programmer. I currently dont use NewShapshot, but}
- { somebody out there might.... especially if you are using DYNAMICALLY}
- { created components on your form.}
- procedure ReSize(ParentForm:TObject);
- procedure NewSnapshot(ParentForm:TObject);
- end;
-
- procedure Register;
-
- implementation
-
- Var ControlList:pControlInfo;
-
- constructor TResizer.Create(AOwner: TComponent);
- Var Count:LongInt;
- Begin
- inherited Create(AOwner);
- { Do my init stuff}
- ResizerInitialized:=False;
- ControlList:=nil;
- End;
-
- destructor TResizer.Destroy;
- Begin
- { Destroy the existing ControlList }
- DeleteControlList(ControlList);
- ResizerInitialized:=False;
- ControlList:=nil;
- inherited Destroy;
- End;
-
- { Recursively setup throw the control list and all containers}
- { and delete all the dynamically allocated objects}
- Procedure TResizer.DeleteControlList(CurCont:pControlInfo);
- Var NextCont:pControlInfo;
- Begin
- While(CurCont<>nil) Do
- Begin
- If((CurCont^.Contains)<>nil) Then
- DeleteControlList(CurCont^.Contains);
- NextCont:=CurCont^.Next;
- FreeMem(CurCont,SizeOf(tControlInfo));
- CurCont:=NextCont;
- End;
- End;
-
- procedure TResizer.GetNewWidthHeight(Sender:TObject;Var NewW,NewH:LongInt);
- var
- Ctl: TControl;
- PageNum: LongInt;
- Begin
- { Determine the type of container component we have then get its}
- { width and height and tag number}
- If(Sender is TForm) Then
- With TForm(Sender) Do
- Begin
- { Since this is a TForm, we want ClientWidth and ClientHeight}
- NewW:=ClientWidth;
- NewH:=ClientHeight;
- End
- Else
- If(Sender is TPanel) Then
- With TPanel(Sender) Do
- Begin
- NewW:=Width;
- NewH:=Height;
- End
- Else
- If(Sender is TGroupBox) Then
- With TGroupBox(Sender) Do
- Begin
- NewW:=Width;
- NewH:=Height;
- End
- Else
- If(Sender is TTabbedNotebook) Then
- begin
- PageNum := (TTabbedNotebook(Sender).PageIndex * 2) + 1;
- Ctl := TTabbedNotebook(Sender).Controls[PageNum];
- With TTabPage(Ctl) Do
- Begin
- NewW:=Width;
- NewH:=Height;
- End;
- end
- Else
- Begin
- { We don't recognize the container, so supply 0 values}
- NewW:=0;
- NewH:=0;
- End;
- End;
-
- Function TResizer.GetClientControlCount(Sender:TObject):LongInt;
- var
- Ctl: TControl;
- PageNum: LongInt;
- Begin
- { Determine the type of container component we have then}
- { return the number of controls on that container}
- If(Sender is TForm) Then
- Result:=TForm(Sender).ControlCount
- Else
- If(Sender is TPanel) Then
- Result:=TPanel(Sender).ControlCount
- Else
- If(Sender is TGroupBox) Then
- Result:=TGroupBox(Sender).ControlCount
- Else
- If(Sender is TTabbedNotebook) Then
- begin
- PageNum := (TTabbedNotebook(Sender).PageIndex * 2) + 1;
- Ctl := TTabbedNotebook(Sender).Controls[PageNum];
- Result := TTabPage(Ctl).ControlCount
- end
- Else
- { We don't recognize the container, so supply a 0 value}
- Result:=0;
- End;
-
-
- Function TResizer.GetClientControlObject(Sender:TObject;Index:LongInt):TControl;
- var
- Ctl: TControl;
- PageNum: LongInt;
- Begin
- If(Sender is TForm) Then
- Result:=TForm(Sender).Controls[Index]
- Else
- If(Sender is TPanel) Then
- Result:=TPanel(Sender).Controls[Index]
- Else
- If(Sender is TGroupBox) Then
- Result:=TGroupBox(Sender).Controls[Index]
- Else
- If(Sender is TTabbedNotebook) Then
- begin
- PageNum := (TTabbedNotebook(Sender).PageIndex * 2) + 1;
- Ctl := TTabbedNotebook(Sender).Controls[PageNum];
- Application.MainForm.Caption := Ctl.ClassName + ' ' + IntToStr(TWinControl(Ctl).ControlCount);
- if Index < TWinControl(Ctl).ControlCount then
- Result := TTabPage(Ctl).Controls[Index]
- else
- Result := nil;
- end
- Else
- Result:=nil;
- End;
-
- Function TResizer.Initialize(Sender:TObject;CWidth,CHeight:LongInt):pControlInfo;
- Var Temp:pControlInfo;
- Count:Integer;
- Begin
- Result:=nil;
- For Count:=0 to (GetClientControlCount(Sender)-1) Do
- Begin
- GetMem(Temp,SizeOf(tControlInfo));
- Temp^.Obj:=GetClientControlObject(Sender,Count);
- With(Temp^) Do
- Begin
- lRatio:=(Obj.Left) / CWidth;
- tRatio:=(Obj.Top) / CHeight;
- wRatio:=(Obj.Width) / CWidth;
- hRatio:=(Obj.Height) / CHeight;
- Contains:=nil;
- Next:=Result;
- End;
- Result:=Temp;
- If((Temp^.Obj is TForm) or
- (Temp^.Obj is TPanel) or
- (Temp^.Obj is TGroupBox) or
- (Temp^.Obj is TTabbedNotebook)) Then
- With(Temp^) Do
- Contains:=Initialize(Obj,Obj.Width,Obj.Height);
- End;
- End;
-
- Procedure TResizer.PerformResize(CurCont:pControlInfo;CWidth,CHeight:LongInt);
- Begin
- While(CurCont<>nil) Do
- Begin
- With(CurCont^) Do
- Begin
- With(Obj) Do
- SetBounds(Round(lRatio*CWidth),Round(tRatio*CHeight),
- Round(wRatio*CWidth),Round(hRatio*CHeight));
- If(Contains<>nil) Then
- PerformResize(Contains,Obj.Width,Obj.Height);
- End;
- CurCont:=CurCont^.Next;
- End;
- End;
-
- procedure TResizer.NewSnapshot(ParentForm:TObject);
- Var NewClientWidth,NewClientHeight:LongInt;
- Begin
- GetNewWidthHeight(ParentForm,NewClientWidth,NewClientHeight);
- { Delete the existing ControlList for this form}
- DeleteControlList(ControlList);
- ControlList:=nil;
- ResizerInitialized:=False;
- { Initialize the ControlList for this form}
- ControlList:=Initialize(ParentForm,NewClientWidth,NewClientHeight);
- If(ControlList<>nil) Then
- { The control list HAS been initialized!}
- ResizerInitialized:=True;
- End;
-
- { This should be called everytime the form is resized (ie in the OnSized}
- { event). Pass OnSized "Sender" parameter to this procedure}
- procedure TResizer.ReSize(ParentForm:TObject);
- Var NewClientWidth,NewClientHeight:LongInt;
- Count:Integer;
- Left,Top,Width,Height:LongInt;
- Begin
- GetNewWidthHeight(ParentForm,NewClientWidth,NewClientHeight);
- If(ResizerInitialized) Then
- { The ControlList already exists, resize the form and its controls}
- PerformResize(ControlList,NewClientWidth,NewClientHeight)
- Else
- { No ControlList exists. Let's create one}
- NewSnapshot(ParentForm);
- End;
-
- { This should be called only if you want to take a NEW shapshot of the}
- { relative positions and sizes of the controls on the form. The paramter}
- { should be the form on which the object resides}
- procedure Register;
- begin
- { Register the RESIZER component}
- RegisterComponents('New VCs', [TResizer]);
- end;
-
- end.
-
-